package asteroids.model.programs.statement;

import java.util.ArrayList;
import java.util.Map;

import be.kuleuven.cs.som.annotate.*;
import asteroids.model.programs.expression.*;
import asteroids.model.programs.type.*;

public class Assignment extends S {

	private String variable;
	private E rhs;
	
	public Assignment(int line, int column, String variable, E rhs) {
		super(line, column);
		this.variable = variable;
		this.rhs = rhs;
	}
	
	@Basic
	public String getVariable(){
		return variable;
	}
	
	@Basic
	public E getRhs(){
		return rhs;
	}

	@Override
	public void execute(T type) {
		type.setValue(rhs.getValue());
		super.setExecuted(true);
	}

	@Override
	public boolean hasSteps() {
		return true;
	}
	
	@Override
	public boolean isAssignment(){
		return true;
	}

	@Override
	public ArrayList<E> getExpressions(){
		ArrayList<E> list = new ArrayList<E>();
		list.add(rhs);
		return list;
	}
	
	public ArrayList<VariableExpression> getVariableExpressions(){
		return getRhs().getVariables();
	}
	
	public String typecheck(Map<String, T> globals){
		T type = globals.get(getVariable());
		String eTypeCheck = getRhs().typecheck();
		if(!eTypeCheck.equals("")) {
			return eTypeCheck;
		}
		if(type == null){
			return "Undefined variable at line " + getLine() + ", column " + getColumn() + ".\n";
		}
		if(rhs.getValue() == null){
			if(type.getClass() == Entity.class || type.getClass() == ShipType.class)
				return "";
			else 
				return "Typecast error at line " + getLine() + ", column " + getColumn() + ".\n";
		}
		if(!type.getClass().isAssignableFrom(rhs.getValue().getClass()))
			return "Typecast error at line " + getLine() + ", column " + getColumn() + ".\n";
		return "";
	}
	
	public boolean hasAction(){
		return false;
	}
}
